home *** CD-ROM | disk | FTP | other *** search
/ OpenGL Superbible (2nd Edition) / OpenGL SuperBible e2.iso / tools / FLTK-1.0.6 / src / fl_rect.cxx < prev    next >
Encoding:
C/C++ Source or Header  |  1999-03-04  |  10.0 KB  |  391 lines

  1. //
  2. // "$Id: fl_rect.cxx,v 1.10 1999/03/04 18:32:14 mike Exp $"
  3. //
  4. // Rectangle drawing routines for the Fast Light Tool Kit (FLTK).
  5. //
  6. // Copyright 1998-1999 by Bill Spitzak and others.
  7. //
  8. // This library is free software; you can redistribute it and/or
  9. // modify it under the terms of the GNU Library General Public
  10. // License as published by the Free Software Foundation; either
  11. // version 2 of the License, or (at your option) any later version.
  12. //
  13. // This library is distributed in the hope that it will be useful,
  14. // but WITHOUT ANY WARRANTY; without even the implied warranty of
  15. // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  16. // Library General Public License for more details.
  17. //
  18. // You should have received a copy of the GNU Library General Public
  19. // License along with this library; if not, write to the Free Software
  20. // Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
  21. // USA.
  22. //
  23. // Please report all bugs and problems to "fltk-bugs@easysw.com".
  24. //
  25.  
  26. // These routines from fl_draw.H are used by the standard boxtypes
  27. // and thus are always linked into an fltk program.
  28. // Also all fl_clip routines, since they are always linked in so
  29. // that minimal update works.
  30.  
  31. #include <FL/Fl_Widget.H>
  32. #include <FL/fl_draw.H>
  33. #include <FL/x.H>
  34.  
  35. void fl_rect(int x, int y, int w, int h) {
  36.   if (w<=0 || h<=0) return;
  37. #ifdef WIN32
  38.   MoveToEx(fl_gc, x, y, 0L); 
  39.   LineTo(fl_gc, x+w-1, y);
  40.   LineTo(fl_gc, x+w-1, y+h-1);
  41.   LineTo(fl_gc, x, y+h-1);
  42.   LineTo(fl_gc, x, y);
  43. #else
  44.   XDrawRectangle(fl_display, fl_window, fl_gc, x, y, w-1, h-1);
  45. #endif
  46. }
  47.  
  48. void fl_rectf(int x, int y, int w, int h) {
  49.   if (w<=0 || h<=0) return;
  50. #ifdef WIN32
  51.   RECT rect;
  52.   rect.left = x; rect.top = y;  
  53.   rect.right = x + w; rect.bottom = y + h;
  54.   FillRect(fl_gc, &rect, fl_brush());
  55. #else
  56.   if (w && h) XFillRectangle(fl_display, fl_window, fl_gc, x, y, w, h);
  57. #endif
  58. }
  59.  
  60. void fl_xyline(int x, int y, int x1) {
  61. #ifdef WIN32
  62.   MoveToEx(fl_gc, x, y, 0L); LineTo(fl_gc, x1+1, y);
  63. #else
  64.   XDrawLine(fl_display, fl_window, fl_gc, x, y, x1, y);
  65. #endif
  66. }
  67.  
  68. void fl_xyline(int x, int y, int x1, int y2) {
  69. #ifdef WIN32
  70.   if (y2 < y) y2--;
  71.   else y2++;
  72.   MoveToEx(fl_gc, x, y, 0L); 
  73.   LineTo(fl_gc, x1, y);
  74.   LineTo(fl_gc, x1, y2);
  75. #else
  76.   XPoint p[3];
  77.   p[0].x = x;  p[0].y = p[1].y = y;
  78.   p[1].x = p[2].x = x1; p[2].y = y2;
  79.   XDrawLines(fl_display, fl_window, fl_gc, p, 3, 0);
  80. #endif
  81. }
  82.  
  83. void fl_xyline(int x, int y, int x1, int y2, int x3) {
  84. #ifdef WIN32
  85.   if(x3 < x1) x3--;
  86.   else x3++;
  87.   MoveToEx(fl_gc, x, y, 0L); 
  88.   LineTo(fl_gc, x1, y);
  89.   LineTo(fl_gc, x1, y2);
  90.   LineTo(fl_gc, x3, y2);
  91. #else
  92.   XPoint p[4];
  93.   p[0].x = x;  p[0].y = p[1].y = y;
  94.   p[1].x = p[2].x = x1; p[2].y = p[3].y = y2;
  95.   p[3].x = x3;
  96.   XDrawLines(fl_display, fl_window, fl_gc, p, 4, 0);
  97. #endif
  98. }
  99.  
  100. void fl_yxline(int x, int y, int y1) {
  101. #ifdef WIN32
  102.   if (y1 < y) y1--;
  103.   else y1++;
  104.   MoveToEx(fl_gc, x, y, 0L); LineTo(fl_gc, x, y1);
  105. #else
  106.   XDrawLine(fl_display, fl_window, fl_gc, x, y, x, y1);
  107. #endif
  108. }
  109.  
  110. void fl_yxline(int x, int y, int y1, int x2) {
  111. #ifdef WIN32
  112.   if (x2 > x) x2++;
  113.   else x2--;
  114.   MoveToEx(fl_gc, x, y, 0L); 
  115.   LineTo(fl_gc, x, y1);
  116.   LineTo(fl_gc, x2, y1);
  117. #else
  118.   XPoint p[3];
  119.   p[0].x = p[1].x = x;  p[0].y = y;
  120.   p[1].y = p[2].y = y1; p[2].x = x2;
  121.   XDrawLines(fl_display, fl_window, fl_gc, p, 3, 0);
  122. #endif
  123. }
  124.  
  125. void fl_yxline(int x, int y, int y1, int x2, int y3) {
  126. #ifdef WIN32
  127.   if(y3<y1) y3--;
  128.   else y3++;
  129.   MoveToEx(fl_gc, x, y, 0L); 
  130.   LineTo(fl_gc, x, y1);
  131.   LineTo(fl_gc, x2, y1);
  132.   LineTo(fl_gc, x2, y3);
  133. #else
  134.   XPoint p[4];
  135.   p[0].x = p[1].x = x;  p[0].y = y;
  136.   p[1].y = p[2].y = y1; p[2].x = p[3].x = x2;
  137.   p[3].y = y3;
  138.   XDrawLines(fl_display, fl_window, fl_gc, p, 4, 0);
  139. #endif
  140. }
  141.  
  142. void fl_line(int x, int y, int x1, int y1) {
  143. #ifdef WIN32
  144.   MoveToEx(fl_gc, x, y, 0L); 
  145.   LineTo(fl_gc, x1, y1);
  146.   // Draw the last point *again* because the GDI line drawing
  147.   // functions will not draw the last point ("it's a feature!"...)
  148.   SetPixel(fl_gc, x1, y1, fl_RGB());
  149. #else
  150.   XDrawLine(fl_display, fl_window, fl_gc, x, y, x1, y1);
  151. #endif
  152. }
  153.  
  154. void fl_line(int x, int y, int x1, int y1, int x2, int y2) {
  155. #ifdef WIN32
  156.   MoveToEx(fl_gc, x, y, 0L); 
  157.   LineTo(fl_gc, x1, y1);
  158.   LineTo(fl_gc, x2, y2);
  159.   // Draw the last point *again* because the GDI line drawing
  160.   // functions will not draw the last point ("it's a feature!"...)
  161.   SetPixel(fl_gc, x2, y2, fl_RGB());
  162. #else
  163.   XPoint p[3];
  164.   p[0].x = x;  p[0].y = y;
  165.   p[1].x = x1; p[1].y = y1;
  166.   p[2].x = x2; p[2].y = y2;
  167.   XDrawLines(fl_display, fl_window, fl_gc, p, 3, 0);
  168. #endif
  169. }
  170.  
  171. void fl_loop(int x, int y, int x1, int y1, int x2, int y2) {
  172. #ifdef WIN32
  173.   MoveToEx(fl_gc, x, y, 0L); 
  174.   LineTo(fl_gc, x1, y1);
  175.   LineTo(fl_gc, x2, y2);
  176.   LineTo(fl_gc, x, y);
  177. #else
  178.   XPoint p[4];
  179.   p[0].x = x;  p[0].y = y;
  180.   p[1].x = x1; p[1].y = y1;
  181.   p[2].x = x2; p[2].y = y2;
  182.   p[3].x = x;  p[3].y = y;
  183.   XDrawLines(fl_display, fl_window, fl_gc, p, 4, 0);
  184. #endif
  185. }
  186.  
  187. void fl_loop(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) {
  188. #ifdef WIN32
  189.   MoveToEx(fl_gc, x, y, 0L); 
  190.   LineTo(fl_gc, x1, y1);
  191.   LineTo(fl_gc, x2, y2);
  192.   LineTo(fl_gc, x3, y3);
  193.   LineTo(fl_gc, x, y);
  194. #else
  195.   XPoint p[5];
  196.   p[0].x = x;  p[0].y = y;
  197.   p[1].x = x1; p[1].y = y1;
  198.   p[2].x = x2; p[2].y = y2;
  199.   p[3].x = x3; p[3].y = y3;
  200.   p[4].x = x;  p[4].y = y;
  201.   XDrawLines(fl_display, fl_window, fl_gc, p, 5, 0);
  202. #endif
  203. }
  204.  
  205. void fl_polygon(int x, int y, int x1, int y1, int x2, int y2) {
  206.   XPoint p[4];
  207.   p[0].x = x;  p[0].y = y;
  208.   p[1].x = x1; p[1].y = y1;
  209.   p[2].x = x2; p[2].y = y2;
  210. #ifdef WIN32
  211.   SelectObject(fl_gc, fl_brush());
  212.   Polygon(fl_gc, p, 3);
  213. #else
  214.   p[3].x = x;  p[3].y = y;
  215.   XFillPolygon(fl_display, fl_window, fl_gc, p, 3, Convex, 0);
  216.   XDrawLines(fl_display, fl_window, fl_gc, p, 4, 0);
  217. #endif
  218. }
  219.  
  220. void fl_polygon(int x, int y, int x1, int y1, int x2, int y2, int x3, int y3) {
  221.   XPoint p[5];
  222.   p[0].x = x;  p[0].y = y;
  223.   p[1].x = x1; p[1].y = y1;
  224.   p[2].x = x2; p[2].y = y2;
  225.   p[3].x = x3; p[3].y = y3;
  226. #ifdef WIN32
  227.   SelectObject(fl_gc, fl_brush());
  228.   Polygon(fl_gc, p, 4);
  229. #else
  230.   p[4].x = x;  p[4].y = y;
  231.   XFillPolygon(fl_display, fl_window, fl_gc, p, 4, Convex, 0);
  232.   XDrawLines(fl_display, fl_window, fl_gc, p, 5, 0);
  233. #endif
  234. }
  235.  
  236. void fl_point(int x, int y) {
  237. #ifdef WIN32
  238.   SetPixel(fl_gc, x, y, fl_RGB());
  239. #else
  240.   XDrawPoint(fl_display, fl_window, fl_gc, x, y);
  241. #endif
  242. }
  243.  
  244. ////////////////////////////////////////////////////////////////
  245.  
  246. #define STACK_SIZE 10
  247. #define STACK_MAX (STACK_SIZE - 1)
  248. static Region rstack[STACK_SIZE];
  249. static int rstackptr=0;
  250. int fl_clip_state_number=0; // used by gl_begin.C to update GL clip
  251.  
  252. #ifndef WIN32
  253. // Missing X call: (is this the fastest way to init a 1-rectangle region?)
  254. // MSWindows equivalent exists, implemented inline in win32.H
  255. Region XRectangleRegion(int x, int y, int w, int h) {
  256.   XRectangle R;
  257.   R.x = x; R.y = y; R.width = w; R.height = h;
  258.   Region r = XCreateRegion();
  259.   XUnionRectWithRegion(&R, r, r);
  260.   return r;
  261. }
  262. #endif
  263.  
  264. // undo any clobbering of clip done by your program:
  265. void fl_restore_clip() {
  266.   fl_clip_state_number++;
  267.   Region r = rstack[rstackptr];
  268. #ifdef WIN32
  269.   SelectClipRgn(fl_gc, r); //if r is NULL, clip is automatically cleared
  270. #else
  271.   if (r) XSetRegion(fl_display, fl_gc, r);
  272.   else XSetClipMask(fl_display, fl_gc, 0);
  273. #endif
  274. }
  275.  
  276. // Replace the top of the clip stack:
  277. void fl_clip_region(Region r) {
  278.   Region oldr = rstack[rstackptr];
  279.   if (oldr) XDestroyRegion(oldr);
  280.   rstack[rstackptr] = r;
  281.   fl_restore_clip();
  282. }
  283.  
  284. // Intersect & push a new clip rectangle:
  285. void fl_clip(int x, int y, int w, int h) {
  286.   Region r;
  287.   if (w > 0 && h > 0) {
  288.     r = XRectangleRegion(x,y,w,h);
  289.     Region current = rstack[rstackptr];
  290.     if (current) {
  291. #ifndef WIN32
  292.       Region temp = XCreateRegion();
  293.       XIntersectRegion(current, r, temp);
  294.       XDestroyRegion(r);
  295.       r = temp;
  296. #else
  297.       CombineRgn(r,r,current,RGN_AND);
  298. #endif
  299.     }
  300.   } else { // make empty clip region:
  301. #ifndef WIN32
  302.     r = XCreateRegion();
  303. #else
  304.     r = CreateRectRgn(0,0,0,0);
  305. #endif
  306.   }
  307.   if (rstackptr < STACK_MAX) rstack[++rstackptr] = r;
  308.   fl_restore_clip();
  309. }
  310.  
  311. // make there be no clip (used by fl_begin_offscreen() only!)
  312. void fl_push_no_clip() {
  313.   if (rstackptr < STACK_MAX) rstack[++rstackptr] = 0;
  314.   fl_restore_clip();
  315. }
  316.  
  317. // pop back to previous clip:
  318. void fl_pop_clip() {
  319.   if (rstackptr > 0) {
  320.     Region oldr = rstack[rstackptr--];
  321.     if (oldr) XDestroyRegion(oldr);
  322.   }
  323.   fl_restore_clip();
  324. }
  325.  
  326. // does this rectangle intersect current clip?
  327. int fl_not_clipped(int x, int y, int w, int h) {
  328.   Region r = rstack[rstackptr];
  329. #ifndef WIN32
  330.   return r ? XRectInRegion(r, x, y, w, h) : 1;
  331. #else
  332.   if (!r) return 1;
  333.   RECT rect;
  334.   rect.left = x; rect.top = y; rect.right = x+w; rect.bottom = y+h;
  335.   return RectInRegion(r,&rect);
  336. #endif
  337. }
  338.  
  339. // return rectangle surrounding intersection of this rectangle and clip:
  340. int fl_clip_box(int x, int y, int w, int h, int& X, int& Y, int& W, int& H){
  341.   X = x; Y = y; W = w; H = h;
  342.   Region r = rstack[rstackptr];
  343.   if (!r) return 0;
  344. #ifndef WIN32
  345.   switch (XRectInRegion(r, x, y, w, h)) {
  346.   case 0: // completely outside
  347.     W = H = 0;
  348.     return 2;
  349.   case 1: // completely inside:
  350.     return 0;
  351.   default: // partial:
  352.     break;
  353.   }
  354.   Region rr = XRectangleRegion(x,y,w,h);
  355.   Region temp = XCreateRegion();
  356.   XIntersectRegion(r, rr, temp);
  357.   XRectangle rect;
  358.   XClipBox(temp, &rect);
  359.   X = rect.x; Y = rect.y; W = rect.width; H = rect.height;
  360.   XDestroyRegion(temp);
  361.   XDestroyRegion(rr);
  362.   return 1;
  363. #else
  364. // The win32 API makes no distinction between partial and complete
  365. // intersection, so we have to check for partial intersection ourselves.
  366. // However, given that the regions may be composite, we have to do
  367. // some voodoo stuff...
  368.   Region rr = XRectangleRegion(x,y,w,h);
  369.   Region temp = CreateRectRgn(0,0,0,0);
  370.   int ret;
  371.   if (CombineRgn(temp, rr, r, RGN_AND) == NULLREGION) { // disjoint
  372.     W = H = 0;
  373.     ret = 2;
  374.   } else if (EqualRgn(temp, rr)) { // complete
  375.     ret = 0;
  376.   } else {    // parital intersection
  377.     RECT rect;
  378.     GetRgnBox(temp, &rect);
  379.     X = rect.left; Y = rect.top; W = rect.right - X; H = rect.bottom - Y;
  380.     ret = 1;
  381.   }
  382.   DeleteObject(temp);
  383.   DeleteObject(rr);
  384.   return ret;
  385. #endif
  386. }
  387.  
  388. //
  389. // End of "$Id: fl_rect.cxx,v 1.10 1999/03/04 18:32:14 mike Exp $".
  390. //
  391.